﻿using System;
using System.Text;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Encodings;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;

namespace HuaXingSDK
{
    public static class RSAForJava
    {
        /// <summary>
        /// KEY 结构体
        /// </summary>
        public struct RSAKEY
        {
            /// <summary>
            /// 公钥
            /// </summary>
            public string PublicKey { get; set; }

            /// <summary>
            /// 私钥
            /// </summary>
            public string PrivateKey { get; set; }
        }

        public static RSAKEY GetKey()
        {
            //RSA密钥对的构造器  
            var keyGenerator = new RsaKeyPairGenerator();

            //RSA密钥构造器的参数  
            var param = new RsaKeyGenerationParameters(
                Org.BouncyCastle.Math.BigInteger.ValueOf(3),
                new SecureRandom(),
                1024, //密钥长度  
                25);
            //用参数初始化密钥构造器  
            keyGenerator.Init(param);
            //产生密钥对  
            var keyPair = keyGenerator.GenerateKeyPair();
            //获取公钥和密钥  
            var publicKey = keyPair.Public;
            var privateKey = keyPair.Private;

            var subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
            var privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);


            var asn1ObjectPublic = subjectPublicKeyInfo.ToAsn1Object();

            var publicInfoByte = asn1ObjectPublic.GetEncoded("UTF-8");
            var asn1ObjectPrivate = privateKeyInfo.ToAsn1Object();
            var privateInfoByte = asn1ObjectPrivate.GetEncoded("UTF-8");

            var item = new RSAKEY()
            {
                PublicKey = Convert.ToBase64String(publicInfoByte),
                PrivateKey = Convert.ToBase64String(privateInfoByte)
            };
            return item;
        }

        private static AsymmetricKeyParameter GetPublicKeyParameter(string s)
        {
            s = s.Replace("\r", "").Replace("\n", "").Replace(" ", "");
            var publicInfoByte = Convert.FromBase64String(s);
            var pubKey = PublicKeyFactory.CreateKey(publicInfoByte);
            return pubKey;
        }

        private static AsymmetricKeyParameter GetPrivateKeyParameter(string s)
        {
            s = s.Replace("\r", "").Replace("\n", "").Replace(" ", "");
            var privateInfoByte = Convert.FromBase64String(s);
            var priKey = PrivateKeyFactory.CreateKey(privateInfoByte);
            return priKey;
        }

        public static byte[] EncryptByPrivateKey(string s, string key, Encoding encoding = null)
        {
            //非对称加密算法，加解密用  
            var engine = new Pkcs1Encoding(new RsaEngine());
            engine.Init(true, GetPrivateKeyParameter(key));
            var data = (encoding ?? Encoding.UTF8).GetBytes(s);
            return engine.ProcessBlock(data, 0, data.Length);
        }

        public static byte[] DecryptByPublicKey(string s, string key, Encoding encoding = null)
        {
            s = s.Replace("\r", "").Replace("\n", "").Replace(" ", "");
            var engine = new Pkcs1Encoding(new RsaEngine());
            engine.Init(false, GetPublicKeyParameter(key));
            var data = Convert.FromBase64String(s);
            return engine.ProcessBlock(data, 0, data.Length);
        }
    }
}
